//===============================================
// Revision: 2014-07-01
//===============================================
#include <stdlib.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <wiringPi.h>
#include <time.h>
#include <string.h>
//============================================
// LED Pin - wiringPi pin 0 is BCM_GPIO 17
// LED Pin - wiringPi pin 3 is BCM_GPIO 22
// LED Pin - wiringPi pin 7 is BCM_GPIO  4
// gcc -Wall -o bessvx bessvx.c -lwiringPi -lm
//============================================
#define	LED_BLINK  0
#define LED_INP    7
#define LED_ON     3

FILE    *ofp;
int     first = 0;
int     p_year=0,p_month=0,p_day=0;
clock_t g_begin,g_now;
time_t  t;
struct  tm ldt;
int     g_prec       = 1; // 1=millisec 2=microsec
float   g_pow_now    = 0.;
int     g_pulse      = 0;
int     g_debug      = 0;
int     g_pulse_rate = 1000;
int     g_log_rate   = 5000;
int     g_server     = 0;
int     g_local      = 1;
int     g_id         = 9999;
struct  timeval start, end,start2, end2;
 
void logPower();
 
//===========================================
void readConf()
{
   FILE  *in,*out;
   char  line[128],key[24];
   long  value = 99;

   in = fopen("/var/www/bessvx/bess.conf","r");
   if(in == NULL)
   {
     printf("Unable to open BESS configuration file");
     // set default
     g_pulse_rate = 1000;
     g_log_rate   = 5000;
     g_prec       = 1;
     g_server     = 0;
     g_local      = 1;
     g_id         = 9999;
     out = fopen("/var/www/bessvx/bess.conf","w");
     fprintf(out,"CLIENT_ID  %d\n",  g_id);
     fprintf(out,"LOG_RATE   %d\n",  g_log_rate);
     fprintf(out,"PRECISION  %d\n",  g_prec);
     fprintf(out,"LOGSERVER  %d\n",  g_server);
     fprintf(out,"LOGLOCAL   %d\n",  g_local);
     fprintf(out,"PULSE_RATE %d\n",  g_pulse_rate);
     fclose(out);
   }
   else
   {
     while (fgets(line,sizeof line,in) != NULL)
     {
        sscanf(line,"%s %ld",key,&value);
        if(strcmp(key,"PULSE_RATE") == 0) g_pulse_rate = value;
        if(strcmp(key,"LOG_RATE")   == 0) g_log_rate   = value;
        if(strcmp(key,"PRECISION")  == 0) g_prec       = (int)value;
        if(strcmp(key,"LOGSERVER")  == 0) g_server     = (int)value;
        if(strcmp(key,"LOGLOCAL")   == 0) g_local      = (int)value;
        if(strcmp(key,"CLIENT_ID")  == 0) g_id         = (int)value;
       // if(strcmp(key,"DEBUG")      == 0) g_debug      = (int)value;
     }
     fclose(in);
   }
   printf("BESS Configuration\n");
   if(g_prec == 2)
   {
     printf("High Precision Mode (microsec)\n");
   }
   else
     printf("Normal Precision Mode\n");


   printf("CLIENT_ID.... %d \n",g_id); 
   printf("PULSE_RATE... %d \n",g_pulse_rate); 
   printf("LOG_RATE..... %d \n",g_log_rate);
   printf("LOG_SERVER... %d \n",g_server);
   printf("LOG_LOCAL.... %d \n",g_local);
   //printf("DEBUG........ %d \n",g_debug);
  
}
//===========================================
void resetClock()
{
    gettimeofday(&start, NULL);
}
//===========================================
float checkClock(int prec)
{
    float ftime;
    long mtime, seconds, useconds;  
    gettimeofday(&end, NULL);
    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;
    if(prec==1)
    {
       mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
       ftime = (float)mtime;
    }
    if(prec==2)
    {
       mtime = ((seconds)*1000000 + useconds) + 0.5;
       ftime = mtime/1000.; // ms
    }
    if(g_debug > 2)printf("C1 Elapsed time: %.3f\n", ftime);
    return(ftime);
}
//===========================================
void resetClock2()
{
    gettimeofday(&start2, NULL);
}
//===========================================
float checkClock2(int prec)
{
    float ftime;
    long mtime, seconds, useconds;  
    gettimeofday(&end2, NULL);
    seconds  = end2.tv_sec  - start2.tv_sec;
    useconds = end2.tv_usec - start2.tv_usec;
    if(prec==1)
    {
       mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
       ftime = (float)mtime;
    }
    if(prec==2)
    {
       mtime = ((seconds)*1000000 + useconds) + 0.5;
       ftime = mtime/1000.; // ms
    }
    if(g_debug > 2)printf("C2 Elapsed time: %ld\n",mtime);
    return(ftime);
}
//===========================================
void getPulse()
{
  float  msec;
  float  power;

  g_pulse++;
  msec = checkClock(g_prec);
  resetClock();

  if(g_pulse_rate == 1000)power = 3600000./msec;
  if(g_pulse_rate == 10000)power = 360000./msec;   
  g_pow_now = g_pow_now + power;
  if(g_debug > 1 )printf("get pulse --- pow=%.3f  msec=%.3f\n",power,msec);
  digitalWrite (LED_BLINK, HIGH);
  delay(1);
  digitalWrite (LED_BLINK, LOW);
}

//===========================================
void logPower()
{
  //long    msec;
  char    sname[200];
  float   x;

     digitalWrite (LED_ON, HIGH);

     x = g_pow_now/g_pulse;
     //pow2 = (float)g_pulse/g_pulse_rate*3600.*1000./g_log_rate*1000.;
     time(&t);
     ldt = *localtime(&t);

     sprintf(sname,"/var/www/bessvx/data/bess-%d-%d-%d.txt",ldt.tm_year+1900,ldt.tm_mon+1,ldt.tm_mday);
     ofp = fopen(sname, "a+");
     fprintf(ofp,"%d,%d,%d,%.3f,%d\n",ldt.tm_hour,ldt.tm_min,ldt.tm_sec,x,g_pulse);
     fclose(ofp);
    
     digitalWrite (LED_ON, LOW);
}

//=======================================================
int main (int argc, char **argv)
{
  int now=0;
  float x;
  char sys[240];

  readConf();

  wiringPiSetup () ;
  //pri = piHiPri(99);

  pinMode (LED_BLINK,OUTPUT) ;
  pinMode (LED_INP,  INPUT);
  pinMode (LED_ON,   OUTPUT);

  digitalWrite (LED_ON, HIGH);
  digitalWrite (LED_BLINK, LOW);

  printf("bessVx running\n");

//INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP
  wiringPiISR (LED_INP, INT_EDGE_FALLING, getPulse) ;

  resetClock2();
  for (;;)
  {
    now = (int)checkClock2(g_prec);

    if(now > g_log_rate && g_pulse > 0) 
    {
       resetClock2();
       if(g_local == 1)
       {
          logPower();
       }
       if(g_server == 1)
       {
          x = g_pow_now/g_pulse;
          sprintf(sys,"wget -q -O download.bessvx \"http://m2m.simuino.com/bessWeb.php?id=%d&pow=%.3f&pulse=%d\"",g_id,x,g_pulse);
	  //printf("%s\n",sys);
	  system(sys);  
       }     
       g_pulse = 0;
       g_pow_now = 0.;
    }

  }

}
